<!DOCTYPE html><html class="theme-next gemini use-motion" lang="zh-Hans"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="theme-color" content="#222"><script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script><link href="//cdn.bootcss.com/pace/1.0.2/themes/pink/pace-theme-flash.css" rel="stylesheet"><style>.pace .pace-progress{background:#1e92fb;height:3px}.pace .pace-progress-inner{box-shadow:0 0 10px #1e92fb,0 0 5px #1e92fb}.pace .pace-activity{border-top-color:#1e92fb;border-left-color:#1e92fb}</style><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css"><link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css"><link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css"><link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4"><link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.ico?v=5.1.4"><link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4"><link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222"><meta name="keywords" content="正则表达式,"><link rel="alternate" href="/atom.xml" title="It is written" type="application/atom+xml"><meta name="description" content="什么叫知识，能指导我们实践的东西才叫知识。 学习一样东西，如果不能使用，最多只能算作纸上谈兵。正则表达式的学习，也不例外。 掌握了正则表达式的语法后，下一步，也是关键的一步，就是在真实世界中使用它。 那么如何使用正则表达式呢？有哪些关键的点呢？本章就解决这个问题。 内容包括：  正则表达式的四种操作 相关API注意要点 真实案例"><meta property="og:type" content="article"><meta property="og:title" content="第七章 正则表达式编程"><meta property="og:url" content="http://king-xiyu.gitee.io/article/dfe4ff41.html"><meta property="og:site_name" content="It is written"><meta property="og:description" content="什么叫知识，能指导我们实践的东西才叫知识。 学习一样东西，如果不能使用，最多只能算作纸上谈兵。正则表达式的学习，也不例外。 掌握了正则表达式的语法后，下一步，也是关键的一步，就是在真实世界中使用它。 那么如何使用正则表达式呢？有哪些关键的点呢？本章就解决这个问题。 内容包括：  正则表达式的四种操作 相关API注意要点 真实案例"><meta property="og:image" content="https://user-gold-cdn.xitu.io/2017/7/12/f56c1319ec49ee892bb73819e9ddefd9?imageView2/0/w/1280/h/960/format/webp/ignore-error/1"><meta property="article:published_time" content="2020-06-29T13:24:58.000Z"><meta property="article:modified_time" content="2020-09-01T00:45:14.033Z"><meta property="article:author" content="King-XiYu"><meta property="article:tag" content="正则表达式"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://user-gold-cdn.xitu.io/2017/7/12/f56c1319ec49ee892bb73819e9ddefd9?imageView2/0/w/1280/h/960/format/webp/ignore-error/1"><script type="text/javascript" id="hexo.configurations">var NexT=window.NexT||{},CONFIG={root:"/",scheme:"Gemini",version:"5.1.4",sidebar:{position:"left",display:"post",offset:12,b2t:!0,scrollpercent:!0,onmobile:!1},fancybox:!0,tabs:!0,motion:{enable:!0,async:!1,transition:{post_block:"fadeIn",post_header:"slideDownIn",post_body:"slideDownIn",coll_header:"slideLeftIn",sidebar:"slideUpIn"}},duoshuo:{userId:"0",author:"博主"},algolia:{applicationID:"",apiKey:"",indexName:"",hits:{per_page:10},labels:{input_placeholder:"Search for Posts",hits_empty:"We didn't find any results for the search: ${query}",hits_stats:"${hits} results found in ${time} ms"}}}</script><link rel="canonical" href="http://king-xiyu.gitee.io/article/dfe4ff41.html"><title>第七章 正则表达式编程 | It is written</title><meta name="generator" content="Hexo 4.2.0"></head><body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans"><div class="container sidebar-position-left page-post-detail"><div class="headband"></div><header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="header-inner"><div class="site-brand-wrapper"><div class="site-meta"><div class="custom-logo-site-title"><a href="/" class="brand" rel="start"><span class="logo-line-before"><i></i></span> <span class="site-title">It is written</span><span class="logo-line-after"><i></i></span></a></div><p class="site-subtitle"></p></div><div class="site-nav-toggle"> <button><span class="btn-bar"></span><span class="btn-bar"></span><span class="btn-bar"></span></button></div></div><nav class="site-nav"><ul id="menu" class="menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="menu-item-icon fa fa-fw fa-home"></i><br> 首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="menu-item-icon fa fa-fw fa-tags"></i><br> 标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="menu-item-icon fa fa-fw fa-th"></i><br> 分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="menu-item-icon fa fa-fw fa-archive"></i><br> 归档</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="menu-item-icon fa fa-fw fa-user"></i><br> 关于</a></li><li class="menu-item menu-item-search"><a href="javascript:;" class="popup-trigger"><i class="menu-item-icon fa fa-search fa-fw"></i><br> 搜索</a></li></ul><div class="site-search"><div class="popup search-popup local-search-popup"><div class="local-search-header clearfix"><span class="search-icon"><i class="fa fa-search"></i></span><span class="popup-btn-close"><i class="fa fa-times-circle"></i></span><div class="local-search-input-wrapper"> <input autocomplete="off" placeholder="搜索..." spellcheck="false" type="text" id="local-search-input"></div></div><div id="local-search-result"></div></div></div></nav></div></header><main id="main" class="main"><div class="main-inner"><div class="content-wrap"><div id="content" class="content"><div id="posts" class="posts-expand"><article class="post post-type-normal" itemscope itemtype="http://schema.org/Article"><div class="post-block"><link itemprop="mainEntityOfPage" href="http://king-xiyu.gitee.io/article/dfe4ff41.html"><span hidden itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="name" content="King-XiYu"><meta itemprop="description" content=""><meta itemprop="image" content="http://ww1.sinaimg.cn/large/007WurYGgy1ge8nxttd9nj302s02s0si.jpg"></span><span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="It is written"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">第七章 正则表达式编程</h1><div class="post-meta"><span class="post-time"><span class="post-meta-item-icon"><i class="fa fa-calendar-o"></i></span> <span class="post-meta-item-text">发表于</span> <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-06-29T21:24:58+08:00">2020-06-29</time> <span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-calendar-check-o"></i></span> <span class="post-meta-item-text">更新于&#58;</span> <time title="更新于" itemprop="dateModified" datetime="2020-09-01T08:45:14+08:00">2020-09-01</time></span> <span class="post-category"><span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-folder-o"></i></span> <span class="post-meta-item-text">分类于</span> <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/" itemprop="url" rel="index"><span itemprop="name">技术栈</span></a></span> ， <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/%E6%8A%80%E6%9C%AF%E6%A0%88/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/" itemprop="url" rel="index"><span itemprop="name">正则表达式</span></a></span></span> <span class="post-comments-count"><span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-comment-o"></i></span><a href="/article/dfe4ff41.html#comments" itemprop="discussionUrl"><span class="post-comments-count valine-comment-count" data-xid="/article/dfe4ff41.html" itemprop="commentCount"></span></a></span> <span id="/article/dfe4ff41.html" class="leancloud_visitors" data-flag-title="第七章 正则表达式编程"><span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-eye"></i></span> <span class="post-meta-item-text">阅读次数&#58;</span><span class="leancloud-visitors-count"></span></span><div class="post-wordcount"><span class="post-meta-item-icon"><i class="fa fa-file-word-o"></i></span> <span class="post-meta-item-text">字数统计&#58;</span> <span title="字数统计">3.8k 字</span> <span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-clock-o"></i></span> <span class="post-meta-item-text">阅读时长 &asymp;</span> <span title="阅读时长">17 分钟</span></div></div></header><div class="post-body" itemprop="articleBody"><p>什么叫知识，能指导我们实践的东西才叫知识。</p><p>学习一样东西，如果不能使用，最多只能算作纸上谈兵。正则表达式的学习，也不例外。</p><p>掌握了正则表达式的语法后，下一步，也是关键的一步，就是在真实世界中使用它。</p><p>那么如何使用正则表达式呢？有哪些关键的点呢？本章就解决这个问题。</p><p>内容包括：</p><ol><li>正则表达式的四种操作</li><li>相关API注意要点</li><li>真实案例</li></ol><a id="more"></a><h2 id="正则表达式的四种操作"><a href="#正则表达式的四种操作" class="headerlink" title="正则表达式的四种操作"></a>正则表达式的四种操作</h2><p>正则表达式是匹配模式，不管如何使用正则表达式，万变不离其宗，都需要先“匹配”。</p><p>有了匹配这一基本操作后，才有其他的操作：验证、切分、提取、替换。</p><p>进行任何相关操作，也需要宿主引擎相关API的配合使用。当然，在JS中，相关API也不多。</p><h3 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h3><p>验证是正则表达式最直接的应用，比如表单验证。</p><p>在说验证之前，先要说清楚匹配是什么概念。</p><p>所谓匹配，就是看目标字符串里是否有满足匹配的子串。因此，“匹配”的本质就是“查找”。</p><p>有没有匹配，是不是匹配上，判断是否的操作，即称为“验证”。</p><p>这里举一个例子，来看看如何使用相关API进行验证操作的。</p><p>比如，判断一个字符串中是否有数字。</p><ul><li>使用<code>search</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\d/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"abc123"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( !!~string.search(regex) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><ul><li>使用<code>test</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\d/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"abc123"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(string) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><ul><li>使用<code>match</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\d/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"abc123"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( !!string.match(regex) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><ul><li>使用<code>exec</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\d/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"abc123"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( !!regex.exec(string) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><p>其中，最常用的是<code>test</code>。</p><h3 id="切分"><a href="#切分" class="headerlink" title="切分"></a>切分</h3><p>匹配上了，我们就可以进行一些操作，比如切分。</p><p>所谓“切分”，就是把目标字符串，切成一段一段的。在JS中使用的是<code>split</code>。</p><p>比如，目标字符串是”html,css,javascript”，按逗号来切分：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/,/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"html,css,javascript"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( string.split(regex) );</span><br><span class="line"><span class="comment">// =&gt; ["html", "css", "javascript"]</span></span><br></pre></td></tr></table></figure><p>又比如，如下的日期格式：</p><blockquote><p>2017/06/26</p><p>2017.06.26</p><p>2017-06-26</p></blockquote><p>可以使用<code>split</code>“切出”年月日：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\D/</span>;</span><br><span class="line"><span class="built_in">console</span>.log( <span class="string">"2017/06/26"</span>.split(regex) );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="string">"2017.06.26"</span>.split(regex) );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="string">"2017-06-26"</span>.split(regex) );</span><br><span class="line"><span class="comment">// =&gt; ["2017", "06", "26"]</span></span><br><span class="line"><span class="comment">// =&gt; ["2017", "06", "26"]</span></span><br><span class="line"><span class="comment">// =&gt; ["2017", "06", "26"]</span></span><br></pre></td></tr></table></figure><h3 id="提取"><a href="#提取" class="headerlink" title="提取"></a>提取</h3><p>虽然整体匹配上了，但有时需要提取部分匹配的数据。</p><p>此时正则通常要使用分组引用（分组捕获）功能，还需要配合使用相关API。</p><p>这里，还是以日期为例，提取出年月日。注意下面正则中的括号：</p><ul><li><code>match</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/^(\d&#123;4&#125;)\D(\d&#123;2&#125;)\D(\d&#123;2&#125;)$/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-26"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( string.match(regex) );</span><br><span class="line"><span class="comment">// =&gt;["2017-06-26", "2017", "06", "26", index: 0, input: "2017-06-26"]</span></span><br></pre></td></tr></table></figure><ul><li><code>exec</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/^(\d&#123;4&#125;)\D(\d&#123;2&#125;)\D(\d&#123;2&#125;)$/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-26"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( regex.exec(string) );</span><br><span class="line"><span class="comment">// =&gt;["2017-06-26", "2017", "06", "26", index: 0, input: "2017-06-26"]</span></span><br></pre></td></tr></table></figure><ul><li><code>test</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/^(\d&#123;4&#125;)\D(\d&#123;2&#125;)\D(\d&#123;2&#125;)$/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-26"</span>;</span><br><span class="line">regex.test(string);</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.$<span class="number">1</span>, <span class="built_in">RegExp</span>.$<span class="number">2</span>, <span class="built_in">RegExp</span>.$<span class="number">3</span> );</span><br><span class="line"><span class="comment">// =&gt; "2017" "06" "26"</span></span><br></pre></td></tr></table></figure><ul><li><code>search</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/^(\d&#123;4&#125;)\D(\d&#123;2&#125;)\D(\d&#123;2&#125;)$/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-26"</span>;</span><br><span class="line">string.search(regex);</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.$<span class="number">1</span>, <span class="built_in">RegExp</span>.$<span class="number">2</span>, <span class="built_in">RegExp</span>.$<span class="number">3</span> );</span><br><span class="line"><span class="comment">// =&gt; "2017" "06" "26"</span></span><br></pre></td></tr></table></figure><ul><li><code>replace</code></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/^(\d&#123;4&#125;)\D(\d&#123;2&#125;)\D(\d&#123;2&#125;)$/</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-26"</span>;</span><br><span class="line"><span class="keyword">var</span> date = [];</span><br><span class="line">string.replace(regex, <span class="function"><span class="keyword">function</span>(<span class="params">match, year, month, day</span>) </span>&#123;</span><br><span class="line">	date.push(year, month, day);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">console</span>.log(date);</span><br><span class="line"><span class="comment">// =&gt; ["2017", "06", "26"]</span></span><br></pre></td></tr></table></figure><p>其中，最常用的是<code>match</code>。</p><h3 id="替换"><a href="#替换" class="headerlink" title="替换"></a>替换</h3><p>找，往往不是目的，通常下一步是为了替换。在JS中，使用<code>replace</code>进行替换。</p><p>比如把日期格式，从yyyy-mm-dd替换成yyyy/mm/dd：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-26"</span>;</span><br><span class="line"><span class="keyword">var</span> today = <span class="keyword">new</span> <span class="built_in">Date</span>( string.replace(<span class="regexp">/-/g</span>, <span class="string">"/"</span>) );</span><br><span class="line"><span class="built_in">console</span>.log( today );</span><br><span class="line"><span class="comment">// =&gt; Mon Jun 26 2017 00:00:00 GMT+0800 (中国标准时间)</span></span><br></pre></td></tr></table></figure><p>这里只是简单地应用了一下<code>replace</code>。但，<code>replace</code>方法是强大的，是需要重点掌握的。</p><h2 id="相关API注意要点"><a href="#相关API注意要点" class="headerlink" title="相关API注意要点"></a>相关API注意要点</h2><p>从上面可以看出用于正则操作的方法，共有6个，字符串实例4个，正则实例2个：</p><blockquote><p>String#search</p><p>String#split</p><p>String#match</p><p>String#replace</p><p>RegExp#test</p><p>RegExp#exec</p></blockquote><p>本文不打算详细地讲解它们的方方面面细节，具体可以参考《JavaScript权威指南》的第三部分。本文重点列出一些容易忽视的地方，以飨读者。</p><h3 id="search和match的参数问题"><a href="#search和match的参数问题" class="headerlink" title="search和match的参数问题"></a>search和match的参数问题</h3><p>我们知道字符串实例的那4个方法参数都支持正则和字符串。</p><p>但<code>search</code>和<code>match</code>，会把字符串转换为正则的。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"2017.06.27"</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( string.search(<span class="string">"."</span>) );</span><br><span class="line"><span class="comment">// =&gt; 0</span></span><br><span class="line"><span class="comment">//需要修改成下列形式之一</span></span><br><span class="line"><span class="built_in">console</span>.log( string.search(<span class="string">"\\."</span>) );</span><br><span class="line"><span class="built_in">console</span>.log( string.search(<span class="regexp">/\./</span>) );</span><br><span class="line"><span class="comment">// =&gt; 4</span></span><br><span class="line"><span class="comment">// =&gt; 4</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( string.match(<span class="string">"."</span>) );</span><br><span class="line"><span class="comment">// =&gt; ["2", index: 0, input: "2017.06.27"]</span></span><br><span class="line"><span class="comment">//需要修改成下列形式之一</span></span><br><span class="line"><span class="built_in">console</span>.log( string.match(<span class="string">"\\."</span>) );</span><br><span class="line"><span class="built_in">console</span>.log( string.match(<span class="regexp">/\./</span>) );</span><br><span class="line"><span class="comment">// =&gt; [".", index: 4, input: "2017.06.27"]</span></span><br><span class="line"><span class="comment">// =&gt; [".", index: 4, input: "2017.06.27"]</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( string.split(<span class="string">"."</span>) );</span><br><span class="line"><span class="comment">// =&gt; ["2017", "06", "27"]</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( string.replace(<span class="string">"."</span>, <span class="string">"/"</span>) );</span><br><span class="line"><span class="comment">// =&gt; "2017/06.27"</span></span><br></pre></td></tr></table></figure><h3 id="match返回结果的格式问题"><a href="#match返回结果的格式问题" class="headerlink" title="match返回结果的格式问题"></a>match返回结果的格式问题</h3><p><code>match</code>返回结果的格式，与正则对象是否有修饰符<code>g</code>有关。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"2017.06.27"</span>;</span><br><span class="line"><span class="keyword">var</span> regex1 = <span class="regexp">/\b(\d+)\b/</span>;</span><br><span class="line"><span class="keyword">var</span> regex2 = <span class="regexp">/\b(\d+)\b/g</span>;</span><br><span class="line"><span class="built_in">console</span>.log( string.match(regex1) );</span><br><span class="line"><span class="built_in">console</span>.log( string.match(regex2) );</span><br><span class="line"><span class="comment">// =&gt; ["2017", "2017", index: 0, input: "2017.06.27"]</span></span><br><span class="line"><span class="comment">// =&gt; ["2017", "06", "27"]</span></span><br></pre></td></tr></table></figure><p>没有<code>g</code>，返回的是标准匹配格式，即，数组的第一个元素是整体匹配的内容，接下来是分组捕获的内容，然后是整体匹配的第一个下标，最后是输入的目标字符串。</p><p>有<code>g</code>，返回的是所有匹配的内容。</p><p>当没有匹配时，不管有无<code>g</code>，都返回<code>null</code>。</p><h3 id="exec比match更强大"><a href="#exec比match更强大" class="headerlink" title="exec比match更强大"></a>exec比match更强大</h3><p>当正则没有<code>g</code>时，使用<code>match</code>返回的信息比较多。但是有<code>g</code>后，就没有关键的信息<code>index</code>了。</p><p>而<code>exec</code>方法就能解决这个问题，它能接着上一次匹配后继续匹配：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"2017.06.27"</span>;</span><br><span class="line"><span class="keyword">var</span> regex2 = <span class="regexp">/\b(\d+)\b/g</span>;</span><br><span class="line"><span class="built_in">console</span>.log( regex2.exec(string) );</span><br><span class="line"><span class="built_in">console</span>.log( regex2.lastIndex);</span><br><span class="line"><span class="built_in">console</span>.log( regex2.exec(string) );</span><br><span class="line"><span class="built_in">console</span>.log( regex2.lastIndex);</span><br><span class="line"><span class="built_in">console</span>.log( regex2.exec(string) );</span><br><span class="line"><span class="built_in">console</span>.log( regex2.lastIndex);</span><br><span class="line"><span class="built_in">console</span>.log( regex2.exec(string) );</span><br><span class="line"><span class="built_in">console</span>.log( regex2.lastIndex);</span><br><span class="line"><span class="comment">// =&gt; ["2017", "2017", index: 0, input: "2017.06.27"]</span></span><br><span class="line"><span class="comment">// =&gt; 4</span></span><br><span class="line"><span class="comment">// =&gt; ["06", "06", index: 5, input: "2017.06.27"]</span></span><br><span class="line"><span class="comment">// =&gt; 7</span></span><br><span class="line"><span class="comment">// =&gt; ["27", "27", index: 8, input: "2017.06.27"]</span></span><br><span class="line"><span class="comment">// =&gt; 10</span></span><br><span class="line"><span class="comment">// =&gt; null</span></span><br><span class="line"><span class="comment">// =&gt; 0</span></span><br></pre></td></tr></table></figure><p>其中正则实例<code>lastIndex</code>属性，表示下一次匹配开始的位置。</p><p>比如第一次匹配了“2017”，开始下标是0，共4个字符，因此这次匹配结束的位置是3，下一次开始匹配的位置是4。</p><p>从上述代码看出，在使用<code>exec</code>时，经常需要配合使用<code>while</code>循环：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"2017.06.27"</span>;</span><br><span class="line"><span class="keyword">var</span> regex2 = <span class="regexp">/\b(\d+)\b/g</span>;</span><br><span class="line"><span class="keyword">var</span> result;</span><br><span class="line"><span class="keyword">while</span> ( result = regex2.exec(string) ) &#123;</span><br><span class="line">	<span class="built_in">console</span>.log( result, regex2.lastIndex );</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// =&gt; ["2017", "2017", index: 0, input: "2017.06.27"] 4</span></span><br><span class="line"><span class="comment">// =&gt; ["06", "06", index: 5, input: "2017.06.27"] 7</span></span><br><span class="line"><span class="comment">// =&gt; ["27", "27", index: 8, input: "2017.06.27"] 10</span></span><br></pre></td></tr></table></figure><h3 id="修饰符g，对exex和test的影响"><a href="#修饰符g，对exex和test的影响" class="headerlink" title="修饰符g，对exex和test的影响"></a>修饰符g，对exex和test的影响</h3><p>上面提到了正则实例的<code>lastIndex</code>属性，表示尝试匹配时，从字符串的<code>lastIndex</code>位开始去匹配。</p><p>字符串的四个方法，每次匹配时，都是从0开始的，即<code>lastIndex</code>属性始终不变。</p><p>而正则实例的两个方法<code>exec</code>、<code>test</code>，当正则是全局匹配时，每一次匹配完成后，都会修改<code>lastIndex</code>。下面让我们以<code>test</code>为例，看看你是否会迷糊：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/a/g</span>;</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(<span class="string">"a"</span>), regex.lastIndex );</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(<span class="string">"aba"</span>), regex.lastIndex );</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(<span class="string">"ababc"</span>), regex.lastIndex );</span><br><span class="line"><span class="comment">// =&gt; true 1</span></span><br><span class="line"><span class="comment">// =&gt; true 3</span></span><br><span class="line"><span class="comment">// =&gt; false 0</span></span><br></pre></td></tr></table></figure><p>注意上面代码中的第三次调用<code>test</code>，因为这一次尝试匹配，开始从下标<code>lastIndex</code>即3位置处开始查找，自然就找不到了。</p><p>如果没有<code>g</code>，自然都是从字符串第0个字符处开始尝试匹配：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/a/</span>;</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(<span class="string">"a"</span>), regex.lastIndex );</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(<span class="string">"aba"</span>), regex.lastIndex );</span><br><span class="line"><span class="built_in">console</span>.log( regex.test(<span class="string">"ababc"</span>), regex.lastIndex );</span><br><span class="line"><span class="comment">// =&gt; true 0</span></span><br><span class="line"><span class="comment">// =&gt; true 0</span></span><br><span class="line"><span class="comment">// =&gt; true 0</span></span><br></pre></td></tr></table></figure><h3 id="test整体匹配时需要使用-和"><a href="#test整体匹配时需要使用-和" class="headerlink" title="test整体匹配时需要使用^和$"></a>test整体匹配时需要使用^和$</h3><p>这个相对容易理解，因为<code>test</code>是看目标字符串中是否有子串匹配正则，即有部分匹配即可。</p><p>如果，要整体匹配，正则前后需要添加开头和结尾：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log( <span class="regexp">/123/</span>.test(<span class="string">"a123b"</span>) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br><span class="line"><span class="built_in">console</span>.log( <span class="regexp">/^123$/</span>.test(<span class="string">"a123b"</span>) );</span><br><span class="line"><span class="comment">// =&gt; false</span></span><br><span class="line"><span class="built_in">console</span>.log( <span class="regexp">/^123$/</span>.test(<span class="string">"123"</span>) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><h3 id="split相关注意事项"><a href="#split相关注意事项" class="headerlink" title="split相关注意事项"></a>split相关注意事项</h3><p><code>split</code>方法看起来不起眼，但要注意的地方有两个的。</p><p>第一，它可以有第二个参数，表示结果数组的最大长度：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"html,css,javascript"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( string.split(<span class="regexp">/,/</span>, <span class="number">2</span>) );</span><br><span class="line"><span class="comment">// =&gt;["html", "css"]</span></span><br></pre></td></tr></table></figure><p>第二，正则使用分组时，结果数组中是包含分隔符的：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"html,css,javascript"</span>;</span><br><span class="line"><span class="built_in">console</span>.log( string.split(<span class="regexp">/(,)/</span>) );</span><br><span class="line"><span class="comment">// =&gt;["html", ",", "css", ",", "javascript"]</span></span><br></pre></td></tr></table></figure><h3 id="使用构造函数需要注意的问题"><a href="#使用构造函数需要注意的问题" class="headerlink" title="使用构造函数需要注意的问题"></a>使用构造函数需要注意的问题</h3><p>一般不推荐使用构造函数生成正则，而应该优先使用字面量。因为用构造函数会多写很多<code>\</code>。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> string = <span class="string">"2017-06-27 2017.06.27 2017/06/27"</span>;</span><br><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\d&#123;4&#125;(-|\.|\/)\d&#123;2&#125;\1\d&#123;2&#125;/g</span>;</span><br><span class="line"><span class="built_in">console</span>.log( string.match(regex) );</span><br><span class="line"><span class="comment">// =&gt; ["2017-06-27", "2017.06.27", "2017/06/27"]</span></span><br><span class="line"></span><br><span class="line">regex = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">"\\d&#123;4&#125;(-|\\.|\\/)\\d&#123;2&#125;\\1\\d&#123;2&#125;"</span>, <span class="string">"g"</span>);</span><br><span class="line"><span class="built_in">console</span>.log( string.match(regex) );</span><br><span class="line"><span class="comment">// =&gt; ["2017-06-27", "2017.06.27", "2017/06/27"]</span></span><br></pre></td></tr></table></figure><h3 id="修饰符"><a href="#修饰符" class="headerlink" title="修饰符"></a>修饰符</h3><p>ES5中修饰符，共3个：</p><blockquote><p><code>g</code> 全局匹配，即找到所有匹配的，单词是global</p><p><code>i</code> 忽略字母大小写，单词ingoreCase</p><p><code>m</code> 多行匹配，只影响<code>^</code>和<code>$</code>，二者变成行的概念，即行开头和行结尾。单词是multiline</p></blockquote><p>当然正则对象也有相应的只读属性：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/\w/img</span>;</span><br><span class="line"><span class="built_in">console</span>.log( regex.global );</span><br><span class="line"><span class="built_in">console</span>.log( regex.ignoreCase );</span><br><span class="line"><span class="built_in">console</span>.log( regex.multiline );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br><span class="line"><span class="comment">// =&gt; true</span></span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><h3 id="source属性"><a href="#source属性" class="headerlink" title="source属性"></a>source属性</h3><p>正则实例对象属性，除了<code>global</code>、<code>ingnoreCase</code>、<code>multiline</code>、<code>lastIndex</code>属性之外，还有一个<code>source</code>属性。</p><p>它什么时候有用呢？</p><p>比如，在构建动态的正则表达式时，可以通过查看该属性，来确认构建出的正则到底是什么：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> className = <span class="string">"high"</span>;</span><br><span class="line"><span class="keyword">var</span> regex = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="string">"(^|\\s)"</span> + className + <span class="string">"(\\s|$)"</span>);</span><br><span class="line"><span class="built_in">console</span>.log( regex.source )</span><br><span class="line"><span class="comment">// =&gt; (^|\s)high(\s|$) 即字符串"(^|\\s)high(\\s|$)"</span></span><br></pre></td></tr></table></figure><h3 id="构造函数属性"><a href="#构造函数属性" class="headerlink" title="构造函数属性"></a>构造函数属性</h3><p>构造函数的静态属性基于所执行的最近一次正则操作而变化。除了是<code>$1</code>,…,<code>$9</code>之外，还有几个不太常用的属性（有兼容性问题）：</p><blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">RegExp.input&#96; 最近一次目标字符串，简写成&#96;RegExp[&quot;$_&quot;]&#96;</span><br><span class="line">&#96;RegExp.lastMatch&#96; 最近一次匹配的文本，简写成&#96;RegExp[&quot;$&amp;&quot;]&#96;</span><br><span class="line">&#96;RegExp.lastParen&#96; 最近一次捕获的文本，简写成&#96;RegExp[&quot;$+&quot;]&#96;</span><br><span class="line">&#96;RegExp.leftContext&#96; 目标字符串中&#96;lastMatch&#96;之前的文本，简写成&#96;RegExp[&quot;$&#96;&quot;]&#96;</span><br><span class="line">&#96;RegExp.rightContext &#96;目标字符串中&#96;lastMatch&#96;之后的文本，简写成&#96;RegExp[&quot;$&#39;&quot;]</span><br></pre></td></tr></table></figure></blockquote><p>测试代码如下：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/([abc])(\d)/g</span>;</span><br><span class="line"><span class="keyword">var</span> string = <span class="string">"a1b2c3d4e5"</span>;</span><br><span class="line">string.match(regex);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.input );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>[<span class="string">"$_"</span>]);</span><br><span class="line"><span class="comment">// =&gt; "a1b2c3d4e5"</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.lastMatch );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>[<span class="string">"$&amp;"</span>] );</span><br><span class="line"><span class="comment">// =&gt; "c3"</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.lastParen );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>[<span class="string">"$+"</span>] );</span><br><span class="line"><span class="comment">// =&gt; "3"</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.leftContext );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>[<span class="string">"$`"</span>] );</span><br><span class="line"><span class="comment">// =&gt; "a1b2"</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>.rightContext );</span><br><span class="line"><span class="built_in">console</span>.log( <span class="built_in">RegExp</span>[<span class="string">"$'"</span>] );</span><br><span class="line"><span class="comment">// =&gt; "d4e5"</span></span><br></pre></td></tr></table></figure><h2 id="真实案例"><a href="#真实案例" class="headerlink" title="真实案例"></a>真实案例</h2><h3 id="使用构造函数生成正则表达式"><a href="#使用构造函数生成正则表达式" class="headerlink" title="使用构造函数生成正则表达式"></a>使用构造函数生成正则表达式</h3><p>我们知道要优先使用字面量来创建正则，但有时正则表达式的主体是不确定的，此时可以使用构造函数来创建。模拟<code>getElementsByClassName</code>方法，就是很能说明该问题的一个例子。</p><p>这里<code>getElementsByClassName</code>函数的实现思路是：</p><ul><li>比如要获取className为”high”的dom元素；</li><li>首先生成一个正则：<code>/(^|\s)high(\s|$)/</code>；</li><li>然后再用其逐一验证页面上的所有dom元素的类名，拿到满足匹配的元素即可。</li></ul><p>代码如下(可以直接复制到本地查看运行效果)：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">&lt;p <span class="class"><span class="keyword">class</span></span>=<span class="string">"high"</span>&gt;<span class="number">1111</span>&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">&lt;p class="high"&gt;2222&lt;/</span>p&gt;</span><br><span class="line">&lt;p&gt;<span class="number">3333</span>&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">&lt;script&gt;</span></span><br><span class="line"><span class="regexp">function getElementsByClassName(className) &#123;</span></span><br><span class="line"><span class="regexp">	var elements = document.getElementsByTagName("*");</span></span><br><span class="line"><span class="regexp">	var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");</span></span><br><span class="line"><span class="regexp">	var result = [];</span></span><br><span class="line"><span class="regexp">	for (var i = 0; i &lt; elements.length; i++) &#123;</span></span><br><span class="line"><span class="regexp">		var element = elements[i];</span></span><br><span class="line"><span class="regexp">		if (regex.test(element.className)) &#123;</span></span><br><span class="line"><span class="regexp">			result.push(element)</span></span><br><span class="line"><span class="regexp">		&#125;</span></span><br><span class="line"><span class="regexp">	&#125;</span></span><br><span class="line"><span class="regexp">	return result;</span></span><br><span class="line"><span class="regexp">&#125;</span></span><br><span class="line"><span class="regexp">var highs = getElementsByClassName('high');</span></span><br><span class="line"><span class="regexp">highs.forEach(function(item) &#123;</span></span><br><span class="line"><span class="regexp">	item.style.color = 'red';</span></span><br><span class="line"><span class="regexp">&#125;);</span></span><br><span class="line"><span class="regexp">&lt;/</span>script&gt;</span><br></pre></td></tr></table></figure><h3 id="使用字符串保存数据"><a href="#使用字符串保存数据" class="headerlink" title="使用字符串保存数据"></a>使用字符串保存数据</h3><p>一般情况下，我们都愿意使用数组来保存数据。但我看到有的框架中，使用的却是字符串。</p><p>使用时，仍需要把字符串切分成数组。虽然不一定用到正则，但总感觉酷酷的，这里分享如下：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> utils = &#123;&#125;;</span><br><span class="line"><span class="string">"Boolean|Number|String|Function|Array|Date|RegExp|Object|Error"</span>.split(<span class="string">"|"</span>).forEach(<span class="function"><span class="keyword">function</span>(<span class="params">item</span>) </span>&#123;</span><br><span class="line">	utils[<span class="string">"is"</span> + item] = <span class="function"><span class="keyword">function</span>(<span class="params">obj</span>) </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> &#123;&#125;.toString.call(obj) == <span class="string">"[object "</span> + item + <span class="string">"]"</span>;</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;);</span><br><span class="line"><span class="built_in">console</span>.log( utils.isArray([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]) );</span><br><span class="line"><span class="comment">// =&gt; true</span></span><br></pre></td></tr></table></figure><h3 id="if语句中使用正则替代-amp-amp"><a href="#if语句中使用正则替代-amp-amp" class="headerlink" title="if语句中使用正则替代&amp;&amp;*"></a>if语句中使用正则替代&amp;&amp;*</h3><p>比如，模拟<code>ready</code>函数，即加载完毕后再执行回调（不兼容ie的）：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> readyRE = <span class="regexp">/complete|loaded|interactive/</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">ready</span>(<span class="params">callback</span>) </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (readyRE.test(<span class="built_in">document</span>.readyState) &amp;&amp; <span class="built_in">document</span>.body) &#123;</span><br><span class="line">		callback()</span><br><span class="line">	&#125; </span><br><span class="line">	<span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="built_in">document</span>.addEventListener(</span><br><span class="line">			<span class="string">'DOMContentLoaded'</span>, </span><br><span class="line">			<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				callback()</span><br><span class="line">			&#125;,</span><br><span class="line">			<span class="literal">false</span></span><br><span class="line">		);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;;</span><br><span class="line">ready(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">	alert(<span class="string">"加载完毕！"</span>)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="使用强大的replace"><a href="#使用强大的replace" class="headerlink" title="使用强大的replace"></a>使用强大的replace</h3><p>因为<code>replace</code>方法比较强大，有时用它根本不是为了替换，只是拿其匹配到的信息来做文章。</p><p>这里以查询字符串（querystring）压缩技术为例，注意下面<code>replace</code>方法中，回调函数根本没有返回任何东西。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">compress</span>(<span class="params">source</span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> keys = &#123;&#125;;</span><br><span class="line">	source.replace(<span class="regexp">/([^=&amp;]+)=([^&amp;]*)/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">full, key, value</span>) </span>&#123;</span><br><span class="line">		keys[key] = (keys[key] ? keys[key] + <span class="string">','</span> : <span class="string">''</span>) + value;</span><br><span class="line">	&#125;);</span><br><span class="line">	<span class="keyword">var</span> result = [];</span><br><span class="line">	<span class="keyword">for</span> (<span class="keyword">var</span> key <span class="keyword">in</span> keys) &#123;</span><br><span class="line">		result.push(key + <span class="string">'='</span> + keys[key]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> result.join(<span class="string">'&amp;'</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( compress(<span class="string">"a=1&amp;b=2&amp;a=3&amp;b=4"</span>) );</span><br><span class="line"><span class="comment">// =&gt; "a=1,3&amp;b=2,4"</span></span><br></pre></td></tr></table></figure><h3 id="综合运用"><a href="#综合运用" class="headerlink" title="综合运用"></a>综合运用</h3><p>最后这里再做个简单实用的正则测试器。</p><p>具体效果如下：</p><p><img src="https://user-gold-cdn.xitu.io/2017/7/12/f56c1319ec49ee892bb73819e9ddefd9?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="image.png"></p><p>代码，直接贴了，相信你能看得懂：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br></pre></td><td class="code"><pre><span class="line">&lt;section&gt;</span><br><span class="line">	&lt;div id=<span class="string">"err"</span>&gt;&lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp">	&lt;input id="regex" placeholder="请输入正则表达式"&gt;</span></span><br><span class="line"><span class="regexp">	&lt;input id="text" placeholder="请输入测试文本"&gt;</span></span><br><span class="line"><span class="regexp">	&lt;button id="run"&gt;测试一下&lt;/</span>button&gt;</span><br><span class="line">	&lt;div id=<span class="string">"result"</span>&gt;&lt;<span class="regexp">/div&gt;</span></span><br><span class="line"><span class="regexp">&lt;/</span>section&gt;</span><br><span class="line">&lt;style&gt;</span><br><span class="line">section&#123;</span><br><span class="line">	display:flex;</span><br><span class="line">	flex-direction:column;</span><br><span class="line">	justify-content:space-around;</span><br><span class="line">	height:<span class="number">300</span>px;</span><br><span class="line">	padding:<span class="number">0</span> <span class="number">200</span>px;</span><br><span class="line">&#125;</span><br><span class="line">section *&#123;</span><br><span class="line">	min-height:<span class="number">30</span>px;</span><br><span class="line">&#125;</span><br><span class="line">#err &#123;</span><br><span class="line">	color:red;</span><br><span class="line">&#125;</span><br><span class="line">#result&#123;</span><br><span class="line">	line-height:<span class="number">30</span>px;</span><br><span class="line">&#125;</span><br><span class="line">.info &#123;</span><br><span class="line">	background:#00c5ff;</span><br><span class="line">	padding:<span class="number">2</span>px;</span><br><span class="line">	margin:<span class="number">2</span>px;</span><br><span class="line">	display:inline-block;</span><br><span class="line">&#125;</span><br><span class="line">&lt;<span class="regexp">/style&gt;</span></span><br><span class="line"><span class="regexp">&lt;script&gt;</span></span><br><span class="line"><span class="regexp">(function() &#123;</span></span><br><span class="line"><span class="regexp">	/</span><span class="regexp">/ 获取相应dom元素</span></span><br><span class="line"><span class="regexp">	var regexInput = document.getElementById("regex");</span></span><br><span class="line"><span class="regexp">	var textInput = document.getElementById("text");</span></span><br><span class="line"><span class="regexp">	var runBtn = document.getElementById("run");</span></span><br><span class="line"><span class="regexp">	var errBox = document.getElementById("err");</span></span><br><span class="line"><span class="regexp">	var resultBox = document.getElementById("result");</span></span><br><span class="line"><span class="regexp">	</span></span><br><span class="line"><span class="regexp">	/</span><span class="regexp">/ 绑定点击事件</span></span><br><span class="line"><span class="regexp">	runBtn.onclick = function() &#123;</span></span><br><span class="line"><span class="regexp">		/</span><span class="regexp">/ 清除错误和结果</span></span><br><span class="line"><span class="regexp">		errBox.innerHTML = "";</span></span><br><span class="line"><span class="regexp">		resultBox.innerHTML = "";</span></span><br><span class="line"><span class="regexp">		</span></span><br><span class="line"><span class="regexp">		/</span><span class="regexp">/ 获取正则和文本</span></span><br><span class="line"><span class="regexp">		var text = textInput.value;</span></span><br><span class="line"><span class="regexp">		var regex = regexInput.value;</span></span><br><span class="line"><span class="regexp">		</span></span><br><span class="line"><span class="regexp">		if (regex == "") &#123;</span></span><br><span class="line"><span class="regexp">			errBox.innerHTML = "请输入正则表达式";</span></span><br><span class="line"><span class="regexp">		&#125; else if (text == "") &#123;</span></span><br><span class="line"><span class="regexp">			errBox.innerHTML = "请输入测试文本";</span></span><br><span class="line"><span class="regexp">		&#125; else &#123;</span></span><br><span class="line"><span class="regexp">			regex = createRegex(regex);</span></span><br><span class="line"><span class="regexp">			if (!regex) return;</span></span><br><span class="line"><span class="regexp">			var result, results = [];</span></span><br><span class="line"><span class="regexp">			</span></span><br><span class="line"><span class="regexp">			/</span><span class="regexp">/ 没有修饰符g的话，会死循环</span></span><br><span class="line"><span class="regexp">			if (regex.global) &#123;</span></span><br><span class="line"><span class="regexp">				while(result = regex.exec(text)) &#123;</span></span><br><span class="line"><span class="regexp">					results.push(result);</span></span><br><span class="line"><span class="regexp">				&#125;</span></span><br><span class="line"><span class="regexp">			&#125; else &#123;</span></span><br><span class="line"><span class="regexp">				results.push(regex.exec(text));</span></span><br><span class="line"><span class="regexp">			&#125;</span></span><br><span class="line"><span class="regexp">						</span></span><br><span class="line"><span class="regexp">			if (results[0] == null) &#123;</span></span><br><span class="line"><span class="regexp">				resultBox.innerHTML = "匹配到0个结果";</span></span><br><span class="line"><span class="regexp">				return;</span></span><br><span class="line"><span class="regexp">			&#125;</span></span><br><span class="line"><span class="regexp">			</span></span><br><span class="line"><span class="regexp">			/</span><span class="regexp">/ 倒序是有必要的</span></span><br><span class="line"><span class="regexp">			for (var i = results.length - 1; i &gt;= 0; i--) &#123;</span></span><br><span class="line"><span class="regexp">				var result = results[i];</span></span><br><span class="line"><span class="regexp">				var match = result[0];</span></span><br><span class="line"><span class="regexp">				var prefix = text.substr(0, result.index);</span></span><br><span class="line"><span class="regexp">				var suffix = text.substr(result.index + match.length);</span></span><br><span class="line"><span class="regexp">				text = prefix </span></span><br><span class="line"><span class="regexp">					+ '&lt;span class="info"&gt;'</span></span><br><span class="line"><span class="regexp">					+ match</span></span><br><span class="line"><span class="regexp">					+ '&lt;/</span>span&gt;<span class="string">'</span></span><br><span class="line"><span class="string">					+ suffix;</span></span><br><span class="line"><span class="string">			&#125;</span></span><br><span class="line"><span class="string">			resultBox.innerHTML = "匹配到" + results.length + "个结果:&lt;br&gt;" + text;</span></span><br><span class="line"><span class="string">		&#125;</span></span><br><span class="line"><span class="string">	&#125;;</span></span><br><span class="line"><span class="string">	</span></span><br><span class="line"><span class="string">	// 生成正则表达式，核心函数</span></span><br><span class="line"><span class="string">	function createRegex(regex) &#123;</span></span><br><span class="line"><span class="string">		try &#123;</span></span><br><span class="line"><span class="string">			if (regex[0] == "/") &#123;</span></span><br><span class="line"><span class="string">				regex = regex.split("/");</span></span><br><span class="line"><span class="string">				regex.shift();</span></span><br><span class="line"><span class="string">				var flags = regex.pop();</span></span><br><span class="line"><span class="string">				regex = regex.join("/");</span></span><br><span class="line"><span class="string">				regex = new RegExp(regex, flags);</span></span><br><span class="line"><span class="string">			&#125; else &#123;</span></span><br><span class="line"><span class="string">				regex = new RegExp(regex, "g");</span></span><br><span class="line"><span class="string">			&#125;</span></span><br><span class="line"><span class="string">			return regex;</span></span><br><span class="line"><span class="string">		&#125; catch(e) &#123;</span></span><br><span class="line"><span class="string">			errBox.innerHTML = "无效的正则表达式";</span></span><br><span class="line"><span class="string">			return false;</span></span><br><span class="line"><span class="string">		&#125;</span></span><br><span class="line"><span class="string">	&#125;</span></span><br><span class="line"><span class="string">&#125;)();</span></span><br><span class="line"><span class="string">&lt;/script&gt;</span></span><br></pre></td></tr></table></figure><h2 id="第七章小结"><a href="#第七章小结" class="headerlink" title="第七章小结"></a>第七章小结</h2><p>相关API的注意点，本章基本上算是一网打尽了。</p><p>至于文中的例子，都是点睛之笔，没有详细解析。如有理解不透的，建议自己敲一敲。</p></div><footer class="post-footer"><div class="post-tags"><a href="/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/" rel="tag"><i class="fa fa-tag"></i> 正则表达式</a></div><div class="post-nav"><div class="post-nav-next post-nav-item"><a href="/article/c8eb66ee.html" rel="next" title="第六章 正则表达式的构建"><i class="fa fa-chevron-left"></i> 第六章 正则表达式的构建</a></div><span class="post-nav-divider"></span><div class="post-nav-prev post-nav-item"> <a href="/article/b0d272e0.html" rel="prev" title="页面适配">页面适配<i class="fa fa-chevron-right"></i></a></div></div></footer></div></article><div class="post-spread"></div></div></div><div class="comments" id="comments"></div></div><div class="sidebar-toggle"><div class="sidebar-toggle-line-wrap"><span class="sidebar-toggle-line sidebar-toggle-line-first"></span><span class="sidebar-toggle-line sidebar-toggle-line-middle"></span><span class="sidebar-toggle-line sidebar-toggle-line-last"></span></div></div><aside id="sidebar" class="sidebar"><div class="sidebar-inner"><ul class="sidebar-nav motion-element"><li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap"> 文章目录</li><li class="sidebar-nav-overview" data-target="site-overview-wrap"> 站点概览</li></ul><section class="site-overview-wrap sidebar-panel"><div class="site-overview"><div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person"> <img class="site-author-image" itemprop="image" src="http://ww1.sinaimg.cn/large/007WurYGgy1ge8nxttd9nj302s02s0si.jpg" alt="King-XiYu"><p class="site-author-name" itemprop="name">King-XiYu</p><p class="site-description motion-element" itemprop="description">有志者事竟成</p></div><nav class="site-state motion-element"><div class="site-state-item site-state-posts"> <a href="/archives/"><span class="site-state-item-count">37</span> <span class="site-state-item-name">日志</span></a></div><div class="site-state-item site-state-categories"> <a href="/categories/index.html"><span class="site-state-item-count">11</span> <span class="site-state-item-name">分类</span></a></div><div class="site-state-item site-state-tags"> <a href="/tags/index.html"><span class="site-state-item-count">10</span> <span class="site-state-item-name">标签</span></a></div></nav><div class="feed-link motion-element"><a href="/atom.xml" rel="alternate"><i class="fa fa-rss"></i> RSS</a></div><div class="links-of-author motion-element"><span class="links-of-author-item"><a href="https://gitee.com/King-XiYu" target="_blank" title="Gitee"><i class="fa fa-fw fa-hand-o-right"></i> Gitee</a></span><span class="links-of-author-item"><a href="https://github.com/King-XiYu" target="_blank" title="GitHub"><i class="fa fa-fw fa-github"></i> GitHub</a></span></div><div class="links-of-blogroll motion-element links-of-blogroll-inline"><div class="links-of-blogroll-title"><i class="fa fa-fw fa-link"></i> Links</div><ul class="links-of-blogroll-list"><li class="links-of-blogroll-item"> <a href="https://www.baidu.com/" title="度娘" target="_blank">度娘</a></li><li class="links-of-blogroll-item"> <a href="https://www.google.com/" title="Google" target="_blank">Google</a></li></ul></div></div></section><section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active"><div class="post-toc"><div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#正则表达式的四种操作"><span class="nav-number">1.</span> <span class="nav-text">正则表达式的四种操作</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#验证"><span class="nav-number">1.1.</span> <span class="nav-text">验证</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#切分"><span class="nav-number">1.2.</span> <span class="nav-text">切分</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#提取"><span class="nav-number">1.3.</span> <span class="nav-text">提取</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#替换"><span class="nav-number">1.4.</span> <span class="nav-text">替换</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#相关API注意要点"><span class="nav-number">2.</span> <span class="nav-text">相关API注意要点</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#search和match的参数问题"><span class="nav-number">2.1.</span> <span class="nav-text">search和match的参数问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#match返回结果的格式问题"><span class="nav-number">2.2.</span> <span class="nav-text">match返回结果的格式问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#exec比match更强大"><span class="nav-number">2.3.</span> <span class="nav-text">exec比match更强大</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#修饰符g，对exex和test的影响"><span class="nav-number">2.4.</span> <span class="nav-text">修饰符g，对exex和test的影响</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#test整体匹配时需要使用-和"><span class="nav-number">2.5.</span> <span class="nav-text">test整体匹配时需要使用^和$</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#split相关注意事项"><span class="nav-number">2.6.</span> <span class="nav-text">split相关注意事项</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#使用构造函数需要注意的问题"><span class="nav-number">2.7.</span> <span class="nav-text">使用构造函数需要注意的问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#修饰符"><span class="nav-number">2.8.</span> <span class="nav-text">修饰符</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#source属性"><span class="nav-number">2.9.</span> <span class="nav-text">source属性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#构造函数属性"><span class="nav-number">2.10.</span> <span class="nav-text">构造函数属性</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#真实案例"><span class="nav-number">3.</span> <span class="nav-text">真实案例</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#使用构造函数生成正则表达式"><span class="nav-number">3.1.</span> <span class="nav-text">使用构造函数生成正则表达式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#使用字符串保存数据"><span class="nav-number">3.2.</span> <span class="nav-text">使用字符串保存数据</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#if语句中使用正则替代-amp-amp"><span class="nav-number">3.3.</span> <span class="nav-text">if语句中使用正则替代&amp;&amp;*</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#使用强大的replace"><span class="nav-number">3.4.</span> <span class="nav-text">使用强大的replace</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#综合运用"><span class="nav-number">3.5.</span> <span class="nav-text">综合运用</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#第七章小结"><span class="nav-number">4.</span> <span class="nav-text">第七章小结</span></a></li></ol></div></div></section><div class="back-to-top"><i class="fa fa-arrow-up"></i> <span id="scrollpercent"><span>0</span>%</span></div></div></aside></div></main><footer id="footer" class="footer"><div class="footer-inner"><div class="copyright">&copy; <span itemprop="copyrightYear">2020</span><span class="with-love"><i class="fa fa-user"></i></span> <span class="author" itemprop="copyrightHolder">宇宙特别帅</span></div></div></footer></div><script type="text/javascript">"[object Function]"!==Object.prototype.toString.call(window.Promise)&&(window.Promise=null)</script><script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script><script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script><script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script><script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script><script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script><script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script><script type="text/javascript" src="/lib/canvas-nest/canvas-nest.min.js"></script><script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script><script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script><script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script><script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script><script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script><script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script><script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script><script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script><script src="//cdn.jsdelivr.net/npm/valine/dist/Valine.min.js"></script><script type="text/javascript">
    var GUEST = ['nick','mail','link'];
    var guest = 'nick,mail,link';
    guest = guest.split(',').filter(item=>{
      return GUEST.indexOf(item)>-1;
    });
    new Valine({
        el: '#comments' ,
        verify: false,
        notify: true,
        appId: '9DODHXKj6rr1cK4oO07iVBX3-gzGzoHsz',
        appKey: 'aJaxxns4VN5WV9nMimT9aSb1',
        placeholder: 'ヾﾉ≧∀≦)o 来呀！吐槽一番吧！',
        avatar:'mp',
        guest_info:guest,
        pageSize:'10' || 10,
    });
  </script><script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "./public/search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script><script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script><script>AV.initialize("9DODHXKj6rr1cK4oO07iVBX3-gzGzoHsz","aJaxxns4VN5WV9nMimT9aSb1")</script><script>function showTime(e){var t=new AV.Query(e),c=[],u=$(".leancloud_visitors");u.each(function(){c.push($(this).attr("id").trim())}),t.containedIn("url",c),t.find().done(function(e){var t=".leancloud-visitors-count";if(0!==e.length){for(var n=0;n<e.length;n++){var o=e[n],i=o.get("url"),s=o.get("time"),r=document.getElementById(i);$(r).find(t).text(s)}for(n=0;n<c.length;n++){i=c[n],r=document.getElementById(i);var l=$(r).find(t);""==l.text()&&l.text(0)}}else u.find(t).text(0)}).fail(function(e,t){console.log("Error: "+t.code+" "+t.message)})}function addCount(i){var e=$(".leancloud_visitors"),s=e.attr("id").trim(),r=e.attr("data-flag-title").trim(),t=new AV.Query(i);t.equalTo("url",s),t.find({success:function(e){if(0<e.length){var t=e[0];t.fetchWhenSave(!0),t.increment("time"),t.save(null,{success:function(e){$(document.getElementById(s)).find(".leancloud-visitors-count").text(e.get("time"))},error:function(e,t){console.log("Failed to save Visitor num, with error message: "+t.message)}})}else{var n=new i,o=new AV.ACL;o.setPublicReadAccess(!0),o.setPublicWriteAccess(!0),n.setACL(o),n.set("title",r),n.set("url",s),n.set("time",1),n.save(null,{success:function(e){$(document.getElementById(s)).find(".leancloud-visitors-count").text(e.get("time"))},error:function(e,t){console.log("Failed to create")}})}},error:function(e){console.log("Error:"+e.code+" "+e.message)}})}$(function(){var e=AV.Object.extend("Counter");1==$(".leancloud_visitors").length?addCount(e):1<$(".post-title-link").length&&showTime(e)})</script><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js"></script><script type="text/javascript" src="/js/src/clipboard-use.js"></script></body></html>